#include "scheduler/reactive_if_then_else_scheduler.h"
#include "../policy/policy_factory.h"
#include "../policy/behavior_tree/behavior_tree_while_do_else_policy.h"

namespace scheduler
{
ReactiveIfThenElseScheduler::ReactiveIfThenElseScheduler(const std::string &name)
    : AbstractScheduler(name)
{
    schedule_policy_ = policy::PolicyFactory<policy::BehaviorTreeWhileDoElsePolicy>::createPolicy(name);
}
ReactiveIfThenElseScheduler::~ReactiveIfThenElseScheduler() = default;

bool ReactiveIfThenElseScheduler::setTask(const task::AbstractTaskConstPtr &task)
{
    EASE_ERROR("reactive if then else scheduler cannot set task");
    throw std::runtime_error("reactive if then else scheduler cannot set task");
}
bool ReactiveIfThenElseScheduler::setScheduler(const AbstractSchedulerConstPtr &scheduler)
{
    EASE_ERROR("reactive if then else scheduler cannot set scheduler");
    throw std::runtime_error("reactive if then else scheduler cannot set scheduler");
}
bool ReactiveIfThenElseScheduler::appendTask(const task::AbstractTaskConstPtr &task)
{
    EASE_ERROR("reactive if then else scheduler cannot append task");
    throw std::runtime_error("reactive if then else scheduler cannot append task");
}
bool ReactiveIfThenElseScheduler::appendScheduler(const AbstractSchedulerConstPtr &scheduler)
{
    EASE_ERROR("reactive if then else scheduler cannot append scheduler");
    throw std::runtime_error("reactive if then else scheduler cannot append scheduler");
}
bool ReactiveIfThenElseScheduler::setWhileConditionTask(const task::AbstractTaskConstPtr &task)
{
    if (task->getTaskType() != task::TaskType::SYNC_REQUEST_TASK)
    {
        EASE_ERROR("reactive if then else scheduler reactive condition must be request task");
        throw std::runtime_error("reactive if then else scheduler reactive condition must be request task");
    }
    auto policy = dynamic_cast<policy::BehaviorTreeWhileDoElsePolicy *>(schedule_policy_.get());
    if (nullptr == policy)
    {
        throw std::runtime_error("reactive if then else scheduler policy case fail");
    }
    return policy->setWhileConditionTask(task);
}
bool ReactiveIfThenElseScheduler::setWhileConditionScheduler(const AbstractSchedulerConstPtr &scheduler)
{
    auto policy = dynamic_cast<policy::BehaviorTreeWhileDoElsePolicy *>(schedule_policy_.get());
    if (nullptr == policy)
    {
        throw std::runtime_error("reactive if then else scheduler policy case fail");
    }
    scheduler_vec_.push_back(scheduler);
    return policy->setWhileConditionPolicy(scheduler->getTaskPolicy());
}
bool ReactiveIfThenElseScheduler::setThenTask(const task::AbstractTaskConstPtr &task)
{
    auto policy = dynamic_cast<policy::BehaviorTreeWhileDoElsePolicy *>(schedule_policy_.get());
    if (nullptr == policy)
    {
        throw std::runtime_error("reactive if then else scheduler policy case fail");
    }
    return policy->setThenTask(task);
}
bool ReactiveIfThenElseScheduler::setThenScheduler(const AbstractSchedulerConstPtr &scheduler)
{
    auto policy = dynamic_cast<policy::BehaviorTreeWhileDoElsePolicy *>(schedule_policy_.get());
    if (nullptr == policy)
    {
        throw std::runtime_error("reactive if then else scheduler policy case fail");
    }
    scheduler_vec_.push_back(scheduler);
    return policy->setThenPolicy(scheduler->getTaskPolicy());
}
bool ReactiveIfThenElseScheduler::setElseTask(const task::AbstractTaskConstPtr &task)
{
    auto policy = dynamic_cast<policy::BehaviorTreeWhileDoElsePolicy *>(schedule_policy_.get());
    if (nullptr == policy)
    {
        throw std::runtime_error("reactive if then else scheduler policy case fail");
    }
    return policy->setElseTask(task);
}
bool ReactiveIfThenElseScheduler::setElseScheduler(const AbstractSchedulerConstPtr &scheduler)
{
    auto policy = dynamic_cast<policy::BehaviorTreeWhileDoElsePolicy *>(schedule_policy_.get());
    if (nullptr == policy)
    {
        throw std::runtime_error("reactive if then else scheduler policy case fail");
    }
    scheduler_vec_.push_back(scheduler);
    return policy->setElsePolicy(scheduler->getTaskPolicy());
}
}
